//
//  ClassController.swift
//  HHSwift
//
//  Created by 华宏 on 2019/4/25.
//  Copyright © 2019年 huahong. All rights reserved.
//

import UIKit
/**
 类型检测 && 转换 (适用于Protocol)
 * is       if shape is HasArea
 * as? as!  if let areaShape = shape as? HasArea
 */

/**
   子类构造函数的继承原则
 * 如果子类没有实现任何父类的指定构造函数，则自动继承父类的所有指定构造函数
 * 如果子类实现了父类的所有指定构造函数，则自动继承父类的所有便利构造函数
 */


//引用类型（指向同一块内存空间，两者有关联）
//MARK:类的定义
//final表示不可再被继承
// 如果没有初值，Class不提供默认的构造函数！
class Person:NSObject {
    // weak must be optional
    // weak must be var, not let!
    // Then, weak can be change to nil
//    weak var manager : Manager?
    var firstName : String
    var lastName  : String
    
    //类型属性，调用Person.highestAge
   static var highestAge : Int = 0
    
    //普通构造函数
    //required必须被子类实现
   required init(firstName:String = "firstName",lastName:String = "lastName") {
        self.firstName = firstName
        self.lastName = lastName
    }
    
    //可失败的构造函数
    init?(fullName:String) {
        
        guard
            let spaceIndex = fullName.range(of: " ")?.lowerBound
        else{
            return nil
            }
        
        
        /// String.SubSequence
        self.firstName = String(fullName[...spaceIndex])
        self.lastName = String(fullName[fullName.index(after: spaceIndex)...])
        
    }
    
    //实例方法
  func fullName() -> String {
        return firstName + " " + lastName
    }
    
    //final:不能被重写
//    final func fullName() -> String {
//        return firstName + " " + lastName
//    }
    
    //类方法
    //class关键字指定的类方法可以被子类重写,但是用static关键字指定的类方法是不能被子类重写的
   static func staicFullName() -> String {
       return  " "
    }
    
    //属性观察器(不会在init函数中被调用，也不会在初始值中被调用)
    // 因此，didSet和willSet对常量let没有意义，因为let只在初始化阶段赋值
    var age:Int = 0{
       
        willSet{
            print("newValue:\(newValue)")
        }
        
        didSet{
            print("oldValue:\(oldValue)")
        }
        
    }
    
    
     // 动态方法解析
      override class func resolveInstanceMethod(_ sel: Selector!) -> Bool {
     
          guard let method = class_getInstanceMethod(self, #selector(runIMP))  else {
              return super.resolveInstanceMethod(sel)
          }
        
          return class_addMethod(self, Selector(("run")), method_getImplementation(method), method_getTypeEncoding(method))
        
        
//        return super.resolveInstanceMethod(sel)

      }
    
      @objc func runIMP() {
          print("runIMP")
      }
    
    
    // 快速消息转发
    override func forwardingTarget(for aSelector: Selector!) -> Any? {
        return Pig()
    }
    
    deinit {
        print("Person is leave")
    }
}

class Pig : NSObject {
    @objc func run() {
        print("Pig run")
    }
}

//MARK:计算属性
struct Point {
    var x = 0.0
    var y = 0.0
}

struct Size {
    var width = 0.0
    var height = 0.0
}

class Rectangle:CustomStringConvertible {
    var origin = Point()
    var size = Size()
    
//延迟属性（懒加载）
  lazy var lazyCenter : Point = {
        
            let centerX = self.origin.x + self.size.width/2
            let centerY = origin.y + size.height/2
            return Point(x: centerX, y: centerY)
    
    }()
    
    init(origin:Point,size:Size) {
        self.origin = origin
        self.size = size
    }
    
    var description: String{
        return String(format: "origin:%f,%f,size:%f,%f", [self.origin.x,self.origin.y ,self.size.width,self.size.height])
    }
}

//MARK:继承，重载
//final表示不可再被继承
final class Student: Person {
    var school: String
//    var classes: String
    
    //两段式构造函数
    //fullName设置默认值
     init(school:String,fullName: String = "hua hong") {
        //构造
        self.school = school
        super.init(fullName: fullName)!
        
        //处理完善其它属性
//        self.lastName = ""
        
    }
    
    //遍利构造函数
    convenience init(schoolSchool:String) {
        let fullName = Student.staicFullName()
        self.init(school: schoolSchool, fullName: fullName)
        
    }
    
    //重写父类的构造函数
    override init?(fullName: String) {
        self.school = ""
        super.init(fullName: fullName)
        
    }
    
//    required必须被子类实现，不需要override
    required init(firstName: String, lastName: String) {
        
        self.school = ""
        super.init(firstName: firstName, lastName: lastName)
        
    }
    
    // TODO: 需要提醒的文字
    override func fullName() -> String {
        return firstName + " " + lastName
    }
    
    //FIXME: 需要修改bug的相关说明
    override var lastName: String{
        didSet{
          self.lastName = oldValue
        }
    }
    
//    override class func staicFullName() -> String {
//        return  " "
//    }
}


class ClassController: BaseViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
      self.title = "类"
        
//        let manager = Manager.defultManager
        let student = Student(school: "")
        let student1 = student
        if student is Student {
            print("is 类型检查")
            //as 类型转换
        }
        
        let a:Bool = student === student1
        
        
        let rect = Rectangle(origin: Point(x: 10, y: 20), size: Size(width: 100, height: 200))
        
        print(rect.description)
        
        
        let p = Person(fullName: "hua hong")
        p?.perform(Selector(("run")))
        
        
    }
    

    

}
